package com.wuxiaofan.api;

import com.alibaba.fastjson.JSONObject;
import com.wuxiaofan.client.GatewayRouteClient;
import com.wuxiaofan.config.UnifiedRouteRepository;
import com.wuxiaofan.service.RefreshRouteService;
import com.wuxiaofan.vo.ReturnResult;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

/**
 * @author wuxiaofan
 * @date 2021/11/3 8:55 上午
 */
@RestController
@RequestMapping("/gateway")
public class GatewayRoutesController {

    @Resource
    private GatewayRouteClient gatewayRouteClient;
    @Autowired
    private RefreshRouteService refreshRouteService;
    @Resource
    private UnifiedRouteRepository unifiedRouteRepository;
    @Resource
    private RouteDefinitionWriter routeDefinitionWriter;

    @GetMapping("/refreshRoutes")
    public ReturnResult refreshRoutes(){
        List<RouteDefinition> routeDefinitionList = getRouteDefinition();
        routeDefinitionList.forEach(routeDefinition -> {
            routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
        });
        unifiedRouteRepository.getRouteDefinitions().subscribe();
        refreshRouteService.refreshRoutes();
        return ReturnResult.success();
    }

    public List<RouteDefinition> getRouteDefinition(){
        List<RouteDefinition> routeDefinitionList = new ArrayList<>();
        ReturnResult returnResult = gatewayRouteClient.all();
        List<Map> resultList = JSONObject.parseArray(JSONObject.toJSONString(returnResult.getResult()),
                Map.class);
        resultList.forEach(map->{
            try {
                RouteDefinition definition = new RouteDefinition();
                definition.setId(ObjectUtils.toString(map.get("routeId")));
                definition.setUri(UriComponentsBuilder.fromHttpUrl("http://127.0.0.1:10010/base/").build().toUri());
                List<PredicateDefinition> predicates = new ArrayList<>();
                PredicateDefinition predicateDefinition = new PredicateDefinition();
                predicateDefinition.setName("Path");
                Map predicateArgsMap = new HashMap();
                predicateArgsMap.put(predicateDefinition.getName(), ObjectUtils.toString(map.get("predicateArgs")));
                predicateDefinition.setArgs(predicateArgsMap);
                predicates.add(predicateDefinition);
                definition.setPredicates(predicates);
                List<FilterDefinition> filters = new ArrayList<>();
                FilterDefinition filterDefinition = new FilterDefinition();
                filterDefinition.setName("StripPrefix");
                Map filterArgsMap = new HashMap();
                filterArgsMap.put(filterDefinition.getName(), ObjectUtils.toString(map.get("filterArgs")));
                filterDefinition.setArgs(filterArgsMap);
                filters.add(filterDefinition);
                definition.setFilters(filters);
                routeDefinitionList.add(definition);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return routeDefinitionList;
    }

}
